#include <iostream>
#include <cmath> //fabs为本库的函数，用来取得浮点数的绝对值
using namespace std;

const int N = 110;       //因为n最大位100
const double eps = 1e-6; //因为浮点数的性质，导致了相等的浮点数相减不一定是0，这里用小于esp这一极小值来判定是否为0

int n;          //用来获取数组阶数
double a[N][N]; //获取输入，注意，数组是存的系数，可能出现小数，所以这里要用浮点数
int k;          //用来存储答案

/*
输出函数
debug专用
*/
void out()
{
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j <= n; ++j)
            cout << a[i][j] << " ";
        cout << endl;
    }
    cout << endl;
    return;
}

/*
高斯消元算法
这里提前约定三种情况
0代表无解
1代表有唯一解
2代表无数解
*/
int gauss()
{
    int c = 0, r = 0; //c为列，r为行，记录现在处理的子矩阵从第几行第几列开始，之所以定义在循环外，是后面判断有无解需要用到这俩
    //这里要特别提醒一点，由于是增广矩阵，所以c的最大值为n+1列，r的最大值为n行，多出来的1为等号右边的值
    int t;                         //工具值，用来记录当前遍历到的列的绝对值最大的元素所对应的列，提前定义防止每次循环定义浪费时间
    for (c = 0, r = 0; c < n; ++c) //这里之所以用c作为循环标准是因为高斯消元的目的是把当前列除了顶列以外的元素消为0
    {
        //第一步，找到当前列绝对值最大的那一行，并且将绝对值最大的那一行换到第一行
        t = r;                                 //从第r行开始找，相当于处理子矩阵
        for (int i = r; i < n; ++i)            //从当前列开始遍历所有列
            if (fabs(a[t][c]) < fabs(a[i][c])) //如果找到更大的
                t = i;                         //那么就记录更大的这一行
        if (fabs(a[t][c]) < eps)
            continue; //如果这一行绝对值最大的都是0，那么这一行就全是0，失去消元的意义，所以直接下一列
        //这里要注意，这个continue会直接把最后面的++r跳过，跳过以后就是处理以下一列，本行为角的子矩阵，可以认为我们对全是0的列的态度是直接抹去
        if (t != r)                      //如果当前的子矩阵顶行不是最大的，那么就需要换
            for (int i = c; i <= n; ++i) //之前的全部都是0，就不用了管了
                swap(a[t][i], a[r][i]);
        //以上，第一步完成
        // out();
        //第二步，将当前行当前列所对应的值配为1
        for (int i = n; i >= c; --i) //注意这里得从后往前消元，从前往后的话第一个消为1了，后面的全部除以一没有了意义
            a[r][i] /= a[r][c];
        //以上，第二步完成
        // out();
        //第三步，将下面所有行的当前列全部消为0
        for (int i = r + 1; i < n; ++i)      //从下一行开始遍历
            if (fabs(a[i][c]) > eps)         //如果当前列不为0
                for (int j = n; j >= c; --j) //那么就用初等行列变换3来消元，这里也需要从后往前消去，不然后面的系数就全部是0了
                {
                    a[i][j] = a[i][j] - a[r][j] * a[i][c];
                    // out();
                }
        //至此，第三步完成
        // out();
        ++r; //然后循环会自动把子矩阵的角缩小，处理下一个子矩阵
    }
    //到这里以后，矩阵基本就是一个倒三角类了，此时倒三角分为三类
    //第一大类，因为r只有在当前行列所指示的值为1且下面都为0的前提下才会前往下一行
    // out();
    if (r < n) //这里用n判定是因为我们最后都会++r，所以如果r指示向n-1且消完后，一定会得到n，这里小于n，代表至少有一列存在r和c同时指向他们时他们全部为0
    {
        //由于由高斯消元的性质可知，n-1~r+1这些行的参数项必定全部为0
        //所以里面又分为两个小类
        //第一种，对应的等号右边的有不为0的值
        for (int i = r; i < n; ++i)
            if (a[i][n] > eps)
                return 0; //那么就是无解
        return 2;         //如果能够到达这里，就代表等号右边也全部为0，第二种情况，有无数解
    }
    //能够到这里，就代表是第二大类，正好全部消完，既有唯一解
    //此时要解方程，就要从后往前代入
    for (int i = n - 1; i > 0; --i)      //从最下面，有高斯消元这个i指定的行列一定为1，用这个1把第i列上面的数字全部消去
        for (int j = i - 1; j >= 0; --j) //当前处理到了哪一列
        {
            a[j][n] = a[j][n] - a[i][n] * a[j][i]; //记住，这里也是从后往前消，不然a[j][i]就变换了
            a[j][i] = a[j][i] - a[i][i] * a[j][i];
            // out();
        }
    return 1; //有唯一解
}

int main()
{
    // freopen("cin.txt", "r", stdin);
    cin >> n;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j <= n; ++j)
            cin >> a[i][j]; //获取输入的增广矩阵
    k = gauss();            //进行高斯消元
    if (k == 0)             //0代表无解
        cout << "No solution";
    else if (k == 2) //2代表多解
        cout << "Infinite group solutions";
    else //不然就是1，代表有唯一解
        for (int i = 0; i < n; ++i)
            printf("%.2lf\n", a[i][n]); //因为高斯消元以后，因为消掉了每一行的所有其他参数，那么如果有唯一解，那么增广矩阵的最后一列就是解
                                        //然后按照题目要求，保留两位小数
    return 0;
}